package com.hjxy.codetools.controller;

import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.StringUtil;
import com.hjxy.codetools.interfa.ArtitleServiceInterface;
import com.hjxy.codetools.interfa.PayOrderServiceInterface;
import com.hjxy.codetools.interfa.TuserServiceInterface;
import com.hjxy.codetools.model.ArtitleModel;
import com.hjxy.codetools.model.PayOrderModel;
import com.hjxy.codetools.model.TuserModel;
import com.hjxy.codetools.util.NetUtil;
import com.hjxy.codetools.util.SnowFlake;
import com.hjxy.codetools.util.wxpay.sdk.WXPayConfig;
import com.hjxy.codetools.util.wxpay.sdk.WXPayConstants;
import com.hjxy.codetools.util.wxpay.sdk.WXPayRequest;
import com.hjxy.codetools.util.wxpay.sdk.WXPayUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.apache.commons.codec.binary.Base64;
import java.sql.Timestamp;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
public class PayController {
    @Autowired
    ArtitleServiceInterface artitleServiceInterface;
    @Autowired
    PayOrderServiceInterface payOrderServiceInterface;
    @Autowired
    TuserServiceInterface tuserServiceInterface;
    WXPayConfig wxPayConfig=new WXPayConfig();
    @RequestMapping(value = "/pcsyt/{randcode}", method = RequestMethod.GET)
    public String pcsyt(@PathVariable("randcode") String randcode,Model model) throws Exception {
        //base64解密
        String realRandCode=new String(Base64.decodeBase64(randcode));
        //查询文章的支付金额
        ArtitleModel artitleModel =  artitleServiceInterface.getArtitleByCode(realRandCode);
        if (artitleModel==null){
            //文章编号 被前端篡改

        }
        else
        {
            //插入订单 返回订单号
            PayOrderModel payOrderModel=new PayOrderModel();
            payOrderModel.setCreatetime( new Timestamp(System.currentTimeMillis()));
            SnowFlake snowFlake=new SnowFlake(0,0);
            String orderCode=String.valueOf(snowFlake.nextId());
            payOrderModel.setOrdercode(orderCode);
            payOrderModel.setPaynum(artitleModel.getNum());
            payOrderModel.setPayresult(0);
            payOrderModel.setPayfor(0);
            payOrderModel.setPayuser(0);
            payOrderModel.setRandcode(realRandCode);
            int orderID= payOrderServiceInterface.insertPayOrder(payOrderModel);
            model.addAttribute("orderCode",orderCode);
            model.addAttribute("payNum",artitleModel.getNum());
        }
        return "pcsyt";
    }

    /**
     *手机收银台页面
     * @param model
     * @param randcode
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/msyt/{randcode}")
    public String msyt(Model model, @PathVariable("randcode") String randcode) throws Exception {
        //base64解密
        String realRandCode=new String(Base64.decodeBase64(randcode));
        //查询文章的支付金额
        ArtitleModel artitleModel =  artitleServiceInterface.getArtitleByCode(realRandCode);
        if (artitleModel==null){
            //文章编号 被前端篡改

        }
        else
        {
            //插入订单 返回订单号
            PayOrderModel payOrderModel=new PayOrderModel();
            payOrderModel.setCreatetime( new Timestamp(System.currentTimeMillis()));
            SnowFlake snowFlake=new SnowFlake(0,0);
            String orderCode=String.valueOf(snowFlake.nextId());
            payOrderModel.setOrdercode(orderCode);
            payOrderModel.setPaynum(artitleModel.getNum());
            payOrderModel.setPayresult(0);
            payOrderModel.setPayfor(0);
            payOrderModel.setPayuser(0);
            payOrderModel.setRandcode(realRandCode);
            int orderID= payOrderServiceInterface.insertPayOrder(payOrderModel);
            model.addAttribute("orderCode",orderCode);
            model.addAttribute("payNum",artitleModel.getNum());
        }
        return "msyt";
    }

    /**
     *手机端用户授权以后
     * 微信回调地址
     * get方式接受
     * @param model
     * @param orCode
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/WechatUerInfo")
    public String WechatUerInfo(Model model, @RequestParam("orCode") String orCode, @RequestParam("code") String code, @RequestParam("state") String state) throws Exception {
        System.out.println("WechatUerInfo--");
        System.out.println("orCode--"+orCode);
        System.out.println("code--"+code);
        System.out.println("state--"+state);
        Map<String, String> parMap = new HashMap<>();
        Map<String, String> signMap = new HashMap<>();
        //去查询对应的价格
        List<PayOrderModel> payOrderModels = payOrderServiceInterface.getPayOrderInfo(parMap);
        if (payOrderModels == null || payOrderModels.size() <= 0) {

            //不存在该订单号 被篡改了
//            resultMap.put("code","50000");
//            resultMap.put("data","未查询到该订单号");
        } else {
            JSONObject jsonObject = null;
            if (code != null) {
                //通过code换取网页授权access_token
                String accessTokenStr = GetAccess_Token(code);
                System.out.println("accessTokenStr--"+accessTokenStr);
                if (accessTokenStr != null && !"".equals(accessTokenStr)) {
                    JSONObject jsonObject1 = JSONObject.parseObject(accessTokenStr);
                    if (jsonObject1 != null) {
                        if (jsonObject1.containsKey("access_token")) {
                            String access_token = jsonObject1.getString("access_token");
                            System.out.println("access_token--"+access_token);
                            if (jsonObject1.containsKey("openid")) {
                                String openid = jsonObject1.getString("openid");

                                //调用微信支付接口
                                int realNum = payOrderModels.get(0).getPaynum();//真实金额
                                parMap.clear();
                                parMap.put("appid", wxPayConfig.getAppID());
                                parMap.put("mch_id", wxPayConfig.getMchID());
                                parMap.put("nonce_str", WXPayUtil.generateNonceStr());
                                parMap.put("body", "支付");
                                parMap.put("out_trade_no", orCode);
                                parMap.put("total_fee", String.valueOf(realNum * 100));
                                // parMap.put("total_fee","1");
                                parMap.put("spbill_create_ip", "xxx");//服务器ip地址
                                parMap.put("notify_url", "http://xxx/api/mwnotifyPay");
                                parMap.put("trade_type", "JSAPI");
                                parMap.put("openid", openid);

                                String SignStr = WXPayUtil.generateSignature(parMap, wxPayConfig.getMchKey());
                                parMap.put("sign", SignStr);

                                String postXml = WXPayUtil.mapToXml(parMap);
                                System.out.println("postXml--"+postXml);
                                WXPayRequest wxPayRequest = new WXPayRequest(wxPayConfig);
                                String resultXml = wxPayRequest.requestOnce(WXPayConstants.DOMAIN_API, WXPayConstants.UNIFIEDORDER_URL_SUFFIX, WXPayUtil.generateNonceStr(), postXml, 5000, 5000, false);
                                System.out.println("resultXml--"+resultXml);
                                Map<String, String> resultxmlMap = WXPayUtil.xmlToMap(resultXml);
                                if (resultxmlMap.containsKey("return_code")) {
                                    if ("SUCCESS".equals(resultxmlMap.get("return_code"))) {

                                        //判断resultcode是否成功
                                        if (resultxmlMap.containsKey("result_code")) {

                                            if ("SUCCESS".equals(resultxmlMap.get("result_code"))) {
                                                //此时才会返回
                                                String prepay_id = resultxmlMap.get("prepay_id");
                                                String nonceStr=WXPayUtil.generateNonceStr();
                                                String timeStamp=String.valueOf(WXPayUtil.getCurrentTimestamp());
                                                //向前台 返回需要的jsapi接口需要的参数

                                                signMap.put("appId", wxPayConfig.getAppID());
                                                signMap.put("nonceStr", nonceStr);
                                                signMap.put("timeStamp", timeStamp);
                                                signMap.put("package", "prepay_id=" + prepay_id);
                                                signMap.put("signType", "MD5");

                                                SignStr = WXPayUtil.generateSignature(signMap, wxPayConfig.getMchKey());
                                                model.addAttribute("appId", wxPayConfig.getAppID());
                                                model.addAttribute("nonceStr",nonceStr);
                                                model.addAttribute("timeStamp",timeStamp);
                                                model.addAttribute("package","prepay_id=" + prepay_id);
                                                model.addAttribute("signType","MD5");
                                                model.addAttribute("paySign",SignStr);
                                                model.addAttribute("orderCode",orCode);
                                                System.out.println("返回--");
                                            } else {
//                                                resultMap.put("code", "50000");
//                                                resultMap.put("data", "业务结果错误，具体请查看日志记录");
                                            }
                                        }
                                    } else {
                                        //统一下单接口返回错误 将错误信息记录到日志中
//                                        resultMap.put("code", "50000");
//                                        resultMap.put("data", "状态码结果错误，具体请查看日志记录");
                                        System.out.println("状态码结果错误，具体请查看日志记录");
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        return "wechatuerinfo";
    }
    /**
     * 通过code换取网页授权access_token
     * @param code
     * @return
     */
    private String GetAccess_Token(String code){
        String url="https://api.weixin.qq.com/sns/oauth2/access_token?appid="+wxPayConfig.getAppID()+"&" +
                "secret="+wxPayConfig.getAppSecret() +
                "&code="+code +
                "&grant_type=authorization_code";
        return NetUtil.httpGet(url);
    }


    /**
     *手机端支付宝
     * 支付按钮点击过后
     * 调用页面模板
     * get方式接受
     * @param model
     * @param orCode
     * @param paynum
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/malipay")
    public String malipay(Model model, @RequestParam("orCode") String orCode,@RequestParam("paynum") String paynum) throws Exception {
        System.out.println("malipay--");
        Map<String,String> parMap=new HashMap<>();
        parMap.put("ordercode",orCode);
        List<PayOrderModel> payOrderModels=payOrderServiceInterface.getPayOrderInfo(parMap);
        if (payOrderModels == null || payOrderModels.size()<=0) {
            //不存在该订单号 被篡改了
//            resultMap.put("code",50000);
//            resultMap.put("data","未查询到该订单号");
            System.out.println("未查询到该订单号");
        }
        else {
            if (!StringUtil.isEmpty(paynum)) {

                if (Integer.parseInt(paynum) != payOrderModels.get(0).getPaynum()) {
                    //金额被篡改

                } else {
                    model.addAttribute("orderCode",orCode);
                    model.addAttribute("payNum",paynum);
                }
            }
        }
        return "malipay";
    }


    /**
     * pc 端支付成功界面
     * @param orCode
     * @param model
     * @return
     * @throws Exception
     */

    @RequestMapping(value = "/pcpaycg/{orCode}", method = RequestMethod.GET)
    public String pcpaycg(Model model, @PathVariable("orCode") String orCode) throws Exception {
        // 订单号 orCode 查询对应的用户名和验证码 到用户表查询
        Map whMap=new HashMap();
        whMap.put("orcode",orCode);
        List<TuserModel> tuserModels= tuserServiceInterface.getTuserByItem(whMap);
        if(tuserModels!=null&&tuserModels.size()>0){
            model.addAttribute("yhm",tuserModels.get(0).getTname());
            model.addAttribute("yzm",tuserModels.get(0).getPass());
        }
//        return "pcpaycg";
        return "mpaycg";
    }

    /**
     * 手机端 端支付成功界面
     * v2版本设计思路为
     * 验证码和登录用户绑定
     *v1版本的话 直接返回一个固定的验证码
     * 对于所有文章有效
     * @param orCode
     * @param model
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/mpaycg/{orCode}")
    public String mpaycg(Model model, @PathVariable("orCode") String orCode) throws Exception {
         // 订单号 orCode 查询对应的用户名和验证码 到用户表查询
        Map whMap=new HashMap();
        whMap.put("orcode",orCode);
        List<TuserModel> tuserModels= tuserServiceInterface.getTuserByItem(whMap);
        if(tuserModels!=null&&tuserModels.size()>0){
            model.addAttribute("yhm",tuserModels.get(0).getTname());
            model.addAttribute("yzm",tuserModels.get(0).getPass());
        }

        return "mpaycg";
    }
}
